#pragma once
#include <iostream>
#include <memory>
#include <dirent.h>
#include <sys/stat.h>
#include <math.h>
#include "yolov5_api.h"
#include <algorithm>
#include <chrono>

using namespace yolov5;

int64_t CurrentTimeMillis()
{
        int64_t timems = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
        return timems;
}
void FindFiles(const std::string &path, std::vector<std::string> &files)
{
        struct stat rst;
        if (stat(const_cast<char *>(path.c_str()), &rst) != 0)
                return;
        DIR *dirpt = opendir(path.data());
        dirent *entry;
        while (entry = readdir(dirpt))
        {
                /* code */
                if (entry->d_type == DT_REG)
                        files.emplace_back(entry->d_name);
        }
        closedir(dirpt);
}

void test_object_detection()
{
        //     std::cout << "test11111111111111" << std::endl;

        //     std::shared_ptr<Yolov5_api>yolov5det = std::make_shared<Yolov5_api>(0,
        //     "/home/user/yyz_workspace_disk/Code/algolib/input_models/onnx_model/retinaface_mobilenet/bupi_last_v10_sim.onnx",
        //     "/home/user/yyz_workspace_disk/Code/algolib/input_models/trt_model"); //原版yolov5 anchor 以及 imagesize=640
        // std::vector<std::vector<std::vector<int>>> anchor_size = {{{36, 20}, {10, 114}, {119, 13}},
        //                                                           {{26, 154}, {18, 422}, {159, 47}},
        //                                                           {{401, 30}, {35, 471}, {431, 72}}}; //bupi

        std::vector<std::vector<std::vector<int>>> anchor_size = {{{10, 13}, {16, 30}, {33, 23}},
                                                                  {{30, 61}, {62, 45}, {59, 119}},
                                                                  {{116, 90}, {156, 198}, {373, 326}}};
        int image_size = 640;

        std::shared_ptr<Yolov5_api> yolov5det = std::make_shared<Yolov5_api>(0,
                                                                             "/home/ubuntujt6/Data/yyz_workspace/code/yolov5_5/yolov5/yolov5/runs/train/exp12/weights/best_sim.onnx",
                                                                             "/home/ubuntujt6/Data/yyz_workspace/code/yolov5_5/yolov5/yolov5/runs/train/exp12/weights",
                                                                             anchor_size, image_size); //原版yolov5 anchor 以及 imagesize=640

        // std::vector<std::string> class_name = {"class1_", "class2_", "class3_"};
        std::vector<std::string> class_name = {"circle"};

        yolov5det->SetClassesName(class_name);

        // cv::Mat img = cv::Mat::zeros(270, 480, CV_8UC3);

        // std::string root="/home/klyr/4T/seg/data/testresult/imgs1/";
        std::string root = "/home/ubuntujt6/Data/yyz_workspace/code/yolov5_5/yolov5/img/";
        std::vector<std::string> files;
        FindFiles(root, files);
        cv::Mat output3;
        for (int i = 0; i < files.size(); i++)
        {
                std::cout << files[i] << std::endl;
                std::string file_path = root + files[i]; // "/home/administrator/imgs/[4]14_21_33.jpg";   // ## '/home/xixi/1.jpg'
                cv::Mat img = cv::imread(file_path);

                if (img.empty())
                {
                        std::cout << "img is empty()" << std::endl;
                        continue;
                }

                cv::Mat img_t = img.clone();

                // algocommon::MatPad mp(img_t.cols, img_t.rows);
                int64_t start_time = CurrentTimeMillis();
                std::vector<std::vector<float>> results;
                // for (int k = 0; k <= 100; k++)
                // {
                //         results = yolov5det->Execute(img);
                // }
                results = yolov5det->Execute(img);

                // std::vector<std::vector<float> >  results = yolov5det->ExecuteGPU(img);
                int64_t end_time = CurrentTimeMillis();

                // std::cout << "---------------------------->test_time:" << end_time - start_time << std::endl;

                std::cout << "results.size():" << results.size() << std::endl;

                for (auto &result : results)
                {

                        //    std::cout<<"result:"<<ceil(result[0])<<std::endl;

                        cv::Point p1(ceil(result[0]), ceil(result[1]));
                        cv::Point p2(floor(result[2]), floor(result[3])); //x,y,x,y,s,cls
                        cv::Point p3(ceil(result[0]), ceil(result[1]));

                        std::string text_Hat = yolov5det->GetClassesName()[result[5]] + std::to_string(result[4]);

                        //    if(result[5]==0)
                        //    {
                        //         cv::rectangle(img_t,p1,p2,cv::Scalar(255, 0, 0), 1, 8, 0);
                        //         cv::putText(img_t,text_Hat,p3,2,1,cv::Scalar(255, 0, 0),1,8,0);
                        //    }
                        //    else if(result[5]==1)
                        //    {
                        //         cv::rectangle(img_t,p1,p2,cv::Scalar(0, 0, 255), 1, 8, 0);
                        //         cv::putText(img_t,text_Hat,p3,2,1,cv::Scalar(0, 0, 255),1,8,0);
                        //    }
                        cv::rectangle(img_t, p1, p2, cv::Scalar(255, 0, 0), 1, 8, 0);
                        cv::putText(img_t, text_Hat, p3, 2, 1, cv::Scalar(255, 0, 0), 1, 8, 0);
                }

                cv::imshow("result", img_t);
                cv::imwrite("/home/ubuntujt6/Data/yyz_workspace/code/yolov5_5/yolov5/img_result/" + files[i], img_t);

                char key = cv::waitKey(1);
                if (key == 'q')
                        break;
                cv::destroyAllWindows();
        }
}
